package com.atguigu.srb.core.service.impl;

import com.atguigu.srb.core.enums.TransTypeEnum;
import com.atguigu.srb.core.hfb.FormHelper;
import com.atguigu.srb.core.hfb.HfbConst;
import com.atguigu.srb.core.hfb.RequestHelper;
import com.atguigu.srb.core.mapper.LendItemMapper;
import com.atguigu.srb.core.mapper.LendMapper;
import com.atguigu.srb.core.mapper.UserAccountMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.pojo.entity.*;
import com.atguigu.srb.core.pojo.vo.InvestVO;
import com.atguigu.srb.core.service.LendItemService;
import com.atguigu.srb.core.service.TransFlowService;
import com.atguigu.srb.core.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 标的出借记录表 服务实现类
 * </p>
 *
 * @author Mr.bilal
 * @since 2023-07-18
 */
@Service
public class LendItemServiceImpl extends ServiceImpl<LendItemMapper, LendItem> implements LendItemService {

    @Autowired
    UserInfoMapper userInfoMapper;

    @Resource
    LendMapper lendMapper;

    @Resource
    UserAccountMapper userAccountMapper;

    @Autowired
    TransFlowService transFlowService;

    @Override
    public BigDecimal getInterestCount(BigDecimal investAmount, BigDecimal lendYearRate, Integer period, Integer returnMethod) {
        BigDecimal bigDecimal = new BigDecimal("0");
        if (returnMethod == 1){
            bigDecimal = Amount1Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        if (returnMethod == 2){
            bigDecimal = Amount2Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        if (returnMethod == 3){
            bigDecimal = Amount3Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        if (returnMethod == 4){
            bigDecimal = Amount4Helper.getInterestCount(investAmount,lendYearRate,period);
        }
        return bigDecimal;
    }

    @Override
    public String commitInvest(String userId, InvestVO investVO) {
        //投标单号
        String lendItemNo = LendNoUtils.getLendItemNo();
        //投标人信息
        UserInfo investUserInfo = userInfoMapper.selectById(userId);

        //标的信息
        Long lendId = investVO.getLendId();
        Lend lend = lendMapper.selectById(lendId);

        //保存lendItem表
        //保存一次用户的投标信息
        QueryWrapper<LendItem> wrapper = new QueryWrapper<>();
        //投资用户id
        wrapper.eq("invest_user_id",userId);
        //标的id
        wrapper.eq("lend_id",investVO.getLendId());

        LendItem lendItem = baseMapper.selectOne(wrapper);
        //有就更改，没有添加
        if (lendItem != null){
            // 提交过投标信息，修改
            lendItem.setInvestAmount(lendItem.getInvestAmount().add(new BigDecimal(investVO.getInvestAmount())));
            //预期收益
            lendItem.setExpectAmount(
                    lendItem.getExpectAmount().add(getInterestCount(new BigDecimal(investVO.getInvestAmount()), lend.getLendYearRate(), lend.getPeriod(), lend.getReturnMethod()))
            );// 预期收益
            baseMapper.updateById(lendItem);
            // 如果提交过投标请求，投标单号用原来的单号
            lendItemNo = lendItem.getLendItemNo();
        }else {
            // 没提交过投标信息，新增
            lendItem = new LendItem();
            BeanUtils.copyProperties(investVO,lendItem);
            //投资用户id
            lendItem.setInvestUserId(Long.parseLong(userId));
            lendItem.setInvestName(investUserInfo.getName());
            //预期收益
            lendItem.setExpectAmount(getInterestCount(new BigDecimal(investVO.getInvestAmount()), lend.getLendYearRate(), lend.getPeriod(), lend.getReturnMethod()));// 预期收益
            //年化利率
            lendItem.setLendYearRate(lend.getLendYearRate());
            //开始日期
            lendItem.setLendStartDate(lend.getLendStartDate());
            //结束日期
            lendItem.setLendEndDate(lend.getLendEndDate());
            //投资金额
            lendItem.setInvestAmount(new BigDecimal(investVO.getInvestAmount()));
            lendItem.setStatus(0);
            // 新增投标单号
            lendItem.setLendItemNo(lendItemNo);
            baseMapper.insert(lendItem);
        }

        // 生成投标表单
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("agentBillNo",lendItemNo);// 投标单号
        paramMap.put("agentProjectCode",lend.getLendNo());// 标的单号
        paramMap.put("agentId", HfbConst.AGENT_ID);
        paramMap.put("voteBindCode",investUserInfo.getBindCode());// 投标人绑定码
        Long borrowerUserId = lend.getUserId();
        UserInfo borrowerUserInfo = userInfoMapper.selectById(borrowerUserId);
        paramMap.put("benefitBindCode",borrowerUserInfo.getBindCode());// 借款人绑定码

        paramMap.put("voteAmt", investVO.getInvestAmount());
        paramMap.put("votePrizeAmt", "0");
        paramMap.put("voteFeeAmt", "0");
        paramMap.put("projectAmt", lend.getAmount()); //标的总金额
        paramMap.put("note", investUserInfo.getName()+"投标");
        paramMap.put("notifyUrl", HfbConst.INVEST_NOTIFY_URL); //检查常量是否正确
        paramMap.put("returnUrl", HfbConst.INVEST_RETURN_URL);
        paramMap.put("agentProjectName", lend.getTitle());
        paramMap.put("timestamp", RequestHelper.getTimestamp());
        String sign = RequestHelper.getSign(paramMap);
        paramMap.put("sign", sign);

        String form = FormHelper.buildForm(HfbConst.INVEST_URL, paramMap);
        return form;
    }

    @Override
    public void notifyCommitInvest(Map<String, Object> param) {
        //商户订单号 == 投资编号
        String lendItemNo = (String)param.get("agentBillNo");
        //项目编号 == 标的编号
        String lendNo = (String)param.get("agentProjectCode");
        //投资人绑定协议号
        String investBindCode = (String)param.get("voteBindCode");
        //投资金额
        String voteAmt = (String)param.get("voteAmt");

        // lend_item--根据（投资编号）查询投标信息并且修改投标状态
        QueryWrapper<LendItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lend_item_no",lendItemNo);
        LendItem lendItem = baseMapper.selectOne(queryWrapper);
        lendItem.setStatus(1);
        lendItem.setInvestTime(LocalDateTime.now());
        baseMapper.updateById(lendItem);

        //lend--根据（标的编号）修改标的投资人数和投资金额
        QueryWrapper<Lend> lendQueryWrapper = new QueryWrapper<>();
        lendQueryWrapper.eq("lend_no",lendNo);
        Lend lend = lendMapper.selectOne(lendQueryWrapper);
        lend.setInvestNum(lend.getInvestNum()+1);
        lend.setInvestAmount(lend.getInvestAmount().add(new BigDecimal(voteAmt)));
        lendMapper.updateById(lend);

        // 修改userAccount，冻结投资人账户
        //先根据投资人绑定的协议号（bind_code）查出投资人的基本信息
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        userInfoQueryWrapper.eq("bind_code",investBindCode);
        UserInfo investUserInfo = userInfoMapper.selectOne(userInfoQueryWrapper);
        //根据投资人的id冻结投资的金额
        QueryWrapper<UserAccount> userAccountQueryWrapper = new QueryWrapper<>();
        userAccountQueryWrapper.eq("user_id",investUserInfo.getId());
        UserAccount investUserAccount = userAccountMapper.selectOne(userAccountQueryWrapper);
        investUserAccount.setAmount(investUserAccount.getAmount().subtract(new BigDecimal(voteAmt)));
        investUserAccount.setFreezeAmount(investUserAccount.getFreezeAmount().add(new BigDecimal(voteAmt)));
        userAccountMapper.updateById(investUserAccount);

        // 生成交易流水
        TransFlow transFlow = new TransFlow();
        transFlow.setTransNo(lendItemNo);
        transFlow.setTransTypeName(TransTypeEnum.INVEST_LOCK.getTransTypeName());
        transFlow.setUserName(investUserInfo.getName());
        transFlow.setTransType(TransTypeEnum.INVEST_LOCK.getTransType());
        transFlow.setTransAmount(new BigDecimal(voteAmt));
        transFlow.setUserId(investUserInfo.getId());
        transFlow.setMemo("投标锁定");
        transFlowService.save(transFlow);
    }

    @Override
    public List<LendItem> getLendItemList(String lendNo) {

        QueryWrapper<Lend> lendQueryWrapper = new QueryWrapper<>();
        lendQueryWrapper.eq("lend_no",lendNo);
        Lend lend = lendMapper.selectOne(lendQueryWrapper);
        QueryWrapper<LendItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lend_id",lend.getId());
        List<LendItem> lendItems = baseMapper.selectList(queryWrapper);
        return lendItems;
    }
}
